package com.loan.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.loan.common.core.domain.PageQuery;
import com.loan.common.core.domain.model.LoginUser;
import com.loan.common.helper.LoginHelper;
import com.loan.common.utils.DateUtils;
import com.loan.common.utils.StringUtils;
import com.loan.system.domain.ApplyEntity;
import com.loan.system.domain.CollectionOrderHandleEntity;
import com.loan.system.domain.RepaymentLogEntity;
import com.loan.system.domain.UserVaEntity;
import com.loan.system.mapper.ApplyMapper;
import com.loan.system.mapper.CollectionOrderHandleMapper;
import com.loan.system.mapper.RepaymentLogMapper;
import com.loan.system.service.RepaymentLogService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author shiguang on 2022/9/7 15:58
 */
@RequiredArgsConstructor
@Service
public class RepaymentLogServiceImpl implements RepaymentLogService {

    private final RepaymentLogMapper repaymentLogMapper;

    private final ApplyMapper applyMapper;

    private final CollectionOrderHandleMapper collectionOrderHandleMapper;

    @Override
    public void savePaymentLog(ApplyEntity applyEntity, String type, Integer paymentMoney, String companyType, String remark) {
        RepaymentLogEntity entity = new RepaymentLogEntity();
        entity.setApplyId(applyEntity.getId());
        entity.setUserId(applyEntity.getUserId());
        entity.setRepaymentMoney(paymentMoney);
        entity.setType(type);
        entity.setStatus("2");
        entity.setRepaymentTime(new Date());
        entity.setCompanyId(applyEntity.getCompanyId());
        entity.setCompanyType(companyType);
        entity.setRemark(remark);
        entity.setCollectionBy(applyEntity.getCollectionBy());
        repaymentLogMapper.insert(entity);
    }

    @Override
    public Page<RepaymentLogEntity> selectRepaymentLogList(RepaymentLogEntity entity, PageQuery pageQuery) {
        return repaymentLogMapper.selectRepaymentLogList(pageQuery.build(), this.buildQueryWrapper(entity));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int revokeRepaymentLogById(String id) {
        RepaymentLogEntity repaymentLogEntity = repaymentLogMapper.selectById(id);
        repaymentLogEntity.setStatus("3");
        repaymentLogEntity.setUpdateTime(new Date());
        repaymentLogMapper.updateById(repaymentLogEntity);
        //修改订单
        ApplyEntity entity = applyMapper.selectById(repaymentLogEntity.getApplyId());
        if ("7".equals(entity.getStatus())) {
            entity.setStatus("6");
            if (ObjectUtil.isNotNull(entity.getCollectionBy())){
                //获取分配记录
                CollectionOrderHandleEntity collectionOrderHandleEntity = collectionOrderHandleMapper.selectOne(new QueryWrapper<CollectionOrderHandleEntity>()
                        .eq("order_id", entity.getId())
                        .gt("callback_amount", 0)
                        .orderByDesc("id")
                        .last("limit 1")
                );
                if (ObjectUtil.isNotNull(collectionOrderHandleEntity) && collectionOrderHandleEntity.getCallbackAmount() >= repaymentLogEntity.getRepaymentMoney()){
                    collectionOrderHandleEntity.setCallbackAmount(collectionOrderHandleEntity.getCallbackAmount() - repaymentLogEntity.getRepaymentMoney());
                    if ("success".equals(collectionOrderHandleEntity.getStatus())
                            || "timeout_all_collect_end".equals(collectionOrderHandleEntity.getStatus())
                            || "timeout_part_collect_end".equals(collectionOrderHandleEntity.getStatus()) ){
                        collectionOrderHandleEntity.setStatus("init");
                    }
                    collectionOrderHandleMapper.updateById(collectionOrderHandleEntity);
                }
            }
        }
        entity.setAlreadyRepayMoney(entity.getAlreadyRepayMoney() - repaymentLogEntity.getRepaymentMoney());
        return applyMapper.updateById(entity);
    }

    /**
     * 增加还款未知状态
     * 当查不到订单，且又存在还款时  则保存还款记录  方便查询
     *
     * @param applyEntity
     * @param type
     * @param amount
     * @param remark
     */
    @Override
    public void savePaymentLogFail(ApplyEntity applyEntity, String type, Integer amount, String companyType, String remark) {
        RepaymentLogEntity entity = new RepaymentLogEntity();
        entity.setApplyId(null);
        entity.setUserId(null);
        entity.setRepaymentMoney(amount);
        entity.setType(type);
        entity.setStatus("2");
        entity.setRepaymentTime(new Date());
        entity.setCompanyId(null);
        entity.setRemark(remark);
        repaymentLogMapper.insert(entity);
    }

    @Override
    public List<RepaymentLogEntity> selectListByApplyIdAndDate(Long applyId, String date, String type) {
        return repaymentLogMapper.selectList(new QueryWrapper<RepaymentLogEntity>()
                .eq("apply_id", applyId)
                .eq("type", type)
                .eq("status", "2")
                .between("repayment_time", DateUtils.toBeginDateByDay(date), DateUtils.toEndDateByDay(date))
        );
    }

    @Override
    public RepaymentLogEntity selectByTransRef(String transRef) {
        return repaymentLogMapper.selectOne(new QueryWrapper<RepaymentLogEntity>().eq("trans_ref",transRef));
    }

    @Override
    public void insert(RepaymentLogEntity entity) {
        repaymentLogMapper.insert(entity);
    }

    private Wrapper<RepaymentLogEntity> buildQueryWrapper(RepaymentLogEntity entity) {
        Map<String, Object> params = entity.getParams();
        QueryWrapper<RepaymentLogEntity> wrapper = Wrappers.query();
        LoginUser loginUser = LoginHelper.getLoginUser();
        wrapper.like(StringUtils.isNotBlank(entity.getUserName()), "u.user_name", entity.getUserName())
                .like(StringUtils.isNotBlank(entity.getUserPhone()), "u.user_phone", entity.getUserPhone())
                .eq(ObjectUtil.isNotNull(entity.getUserId()), "rl.user_id", entity.getUserId())
                .eq(ObjectUtil.isNotNull(loginUser.getCompanyId()), "rl.company_id", loginUser.getCompanyId())
                .eq(StringUtils.isNotBlank(entity.getStatus()), "rl.status", entity.getStatus())
                .eq(StringUtils.isNotBlank(entity.getType()), "rl.type", entity.getType())
                .like(StringUtils.isNotBlank(entity.getOrderSn()), "ua.order_sn", entity.getOrderSn())
                .between(params.get("beginTime") != null && params.get("endTime") != null,
                        "rl.create_time", DateUtils.toBeginDateByDay(params.get("beginTime")), DateUtils.toEndDateByDay(params.get("endTime")))
                .orderByDesc("rl.create_time");
        return wrapper;
    }
}
